<script setup>
import { ref, computed, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import logger from '@/utils/logger'
import { formatDateTime, getNowDateTime } from '@/utils/dayjs'
import { saveGoodsOutbound, getGoodsOutboundById } from '@/api/goodsOutbound'
import StockSelector from './StockSelector.vue'
import { generateOrderNo } from '@/utils/generateOrderNo'
import { useUserStore } from '@/stores/user'

/**
 * @description 定义组件属性
 */
const props = defineProps({
  // 0: 创建 1: 编辑 2: 审核 3: 预览
  mode: {
    type: Number,
    default: 0,
  },
  // 当前出库单（编辑 / 预览 时用）
  currentOutbound: {
    type: Object,
    default: null,
  },
})

/**
 * @description 定义事件
 * @param {Function} success 成功回调
 * @param {Function} close 关闭回调
 */
const emit = defineEmits(['success', 'close'])

/**
 * @description 用户信息存储
 */
const userStore = useUserStore()
/**
 * @description 当前用户名称
 */
const currentUser = computed(() => userStore.nickname || '未登录')

/**
 * @description 表单引用
 */
const formRef = ref(null)
/**
 * @description 商品选择器可见状态
 */
const selectorVisible = ref(false)
/**
 * @description 加载状态
 */
const loading = ref(false)

/**
 * @description 表单数据
 */
const formData = ref({
  goodsOutboundMId: '',
  outboundNo: generateOrderNo('CK'),
  outboundTime: getNowDateTime(),
  operatorId: '',
  operatorName: currentUser.value,
  isCheck: false,
  checkerId: '',
  checkerName: '',
  checkTime: '',
  notes: '',
  pzGoodsOutboundDList: [],
})

/**
 * @description 已选择的商品列表，与表单明细共用同一引用，避免深度 watch
 */
const selectedRawGoods = computed({
  get: () => formData.value.pzGoodsOutboundDList,
  set: (val) => {
    // 为每个商品设置默认出库数量
    formData.value.pzGoodsOutboundDList = val.map((item) => ({
      ...item,
      outQuantity: item.outQuantity || 1,
    }))
  },
})

/**
 * @description 表单验证规则
 */
const rules = {
  outboundNo: [
    { required: true, message: '请输入出库单号', trigger: 'blur' },
    { min: 3, max: 50, message: '长度在 3 到 50 个字符', trigger: 'blur' },
  ],
  operatorName: [{ required: true, message: '请输入出库人', trigger: 'blur' }],
  pzGoodsOutboundDList: [
    { required: true, type: 'array', min: 1, message: '至少添加一件商品', trigger: 'change' },
  ],
}

/**
 * @description 是否为编辑模式
 */
const isEdit = computed(() => !!formData.value.goodsOutboundMId)

/**
 * @description 是否为只读模式 (审核/预览)
 */
const isReadonly = computed(() => props.mode === 2 || props.mode === 3)

/**
 * @description 是否隐藏底部按钮
 */
const hideFooter = computed(() => false)

// 已不再需要 handleSelectedGoodsChange 与深度 watch

/**
 * @description 打开商品选择器
 */
function openGoodsSelector() {
  selectorVisible.value = true
}

/**
 * @description 处理选择器关闭事件
 */
function handleSelectorClose() {
  selectorVisible.value = false
}

/**
 * @description 删除商品
 * @param {Object} item 要删除的商品行
 */
function removeGoods(item) {
  const index = formData.value.pzGoodsOutboundDList.findIndex((g) => g === item)
  if (index !== -1) {
    // 由于 selectedRawGoods 与表单共用同一数组，只需一次 splice 即可
    formData.value.pzGoodsOutboundDList.splice(index, 1)
  }
}

/**
 * @description 验证表单数据
 * @returns {Promise<boolean>} 验证结果
 */
async function validateForm() {
  if (!formRef.value) return false

  if (!formData.value.outboundNo?.trim()) {
    ElMessage.error('出库单号不能为空')
    return false
  }

  if (!formData.value.pzGoodsOutboundDList?.length) {
    ElMessage.warning('请至少添加一件商品')
    return false
  }

  try {
    const valid = await formRef.value.validate().catch(() => false)
    if (!valid) {
      ElMessage.error('请填写必填项')
      return false
    }

    for (const item of formData.value.pzGoodsOutboundDList) {
      if (!item.outQuantity || item.outQuantity <= 0) {
        ElMessage.warning(`商品 ${item.goodsName} 的出库数量必须大于0`)
        return false
      }
    }
    return true
  } catch (error) {
    logger.error('表单验证失败', error)
    ElMessage.error('表单验证失败')
    return false
  }
}

/**
 * @description 提交表单
 * @param {Number} editType 编辑类型 0:新增 1:编辑 2:审核
 */
async function submitForm(editType) {
  const valid = await validateForm()
  if (!valid) return

  try {
    loading.value = true

    const submitData = {
      ...formData.value,
      outboundTime:
        typeof formData.value.outboundTime === 'string'
          ? formData.value.outboundTime
          : formatDateTime(formData.value.outboundTime, 'YYYY-MM-DD HH:mm:ss'),
      isCheck: editType === 2 ? true : formData.value.isCheck,
      checkTime:
        editType === 2
          ? formatDateTime(new Date(), 'YYYY-MM-DD HH:mm:ss')
          : formData.value.checkTime
            ? formatDateTime(formData.value.checkTime, 'YYYY-MM-DD HH:mm:ss')
            : null,

      pzGoodsOutboundDList: formData.value.pzGoodsOutboundDList.map((item) => ({
        goodsOutboundDId: item.goodsOutboundDId || '',
        goodsOutboundMId: formData.value.goodsOutboundMId,
        dealerGoodsStoreId: item.dealerGoodsStoreId,
        outQuantity: item.outQuantity,
      })),
      editType,
    }

    // 移除调试日志
    const res = await saveGoodsOutbound(submitData)

    if (res.success) {
      ElMessage.success(editType === 2 ? '审核成功' : isEdit.value ? '修改成功' : '添加成功')
      emit('success')
      emit('close')
    } else {
      ElMessage.error(res.msg || '保存失败')
    }
  } catch (error) {
    logger.error('保存出库单失败', error)
    ElMessage.error('保存失败')
  } finally {
    loading.value = false
  }
}

/**
 * @description 取消提交
 */
function cancelSubmit() {
  emit('close')
}

/**
 * @description 创建模式初始化表单
 */
function createMode() {
  formData.value = {
    goodsOutboundMId: '',
    outboundNo: generateOrderNo('CK'),
    outboundTime: getNowDateTime(),
    operatorId: '',
    operatorName: currentUser.value,
    isCheck: false,
    checkerId: '',
    checkerName: '',
    checkTime: '',
    notes: '',
    pzGoodsOutboundDList: [],
  }
}

/**
 * @description 编辑模式加载数据
 */
async function editMode() {
  loading.value = true
  try {
    const res = await getGoodsOutboundById(props.currentOutbound.goodsOutboundMId)
    if (!res.success) {
      ElMessage.error(res.msg || '获取出库单失败')
      return
    }
    const data = res.data
    // 如果有商品明细，处理商品列表
    if (Array.isArray(data.pzGoodsOutboundDList) && data.pzGoodsOutboundDList.length) {
      // 只提取表格中实际需要展示的字段
      data.pzGoodsOutboundDList = data.pzGoodsOutboundDList.map((item) => {
        // 只保留必要的字段
        const goodsItem = {
          goodsOutboundDId: item.goodsOutboundDId,
          dealerGoodsStoreId: item.dealerGoodsStoreId,
          goodsName: item.goodsName,
          goodsPicture: item.goodsPicture,
          specifications: item.specifications,
          unit: item.unit,
          quantity: item.quantity, // 库存数量
          outQuantity: item.outQuantity, // 出库数量
        }
        // 同步更新到selectedRawGoods
        // selectedRawGoods.value.push({ ...goodsItem }) // 移除此行，因为 selectedRawGoods 与表单共用同一数组
        return goodsItem
      })
    }

    // 更新表单数据
    formData.value = data
  } catch (error) {
    logger.error('获取出库单详情失败', error)
    ElMessage.error('获取出库单详情失败')
  }
  loading.value = false
}

/**
 * @description 初始化表单数据
 */
function initFormData() {
  switch (props.mode) {
    case 0:
      createMode()
      break
    case 1:
    case 2:
    case 3:
      editMode()
      break
  }
}

/**
 * @description 组件挂载时执行
 */
onMounted(initFormData)
</script>

<template>
  <!-- 商品选择器对话框 -->
  <el-dialog
    v-model="selectorVisible"
    title="勾选需要出库的商品"
    width="80%"
    append-to-body
    align-center
    destroy-on-close
  >
    <StockSelector v-model:selectedGoods="selectedRawGoods" @close="handleSelectorClose" />
  </el-dialog>

  <!-- 出库单表单 -->
  <div class="outbound-container">
    <!-- 出库单标题 -->
    <div class="receipt-header">
      <div class="receipt-title">出库单</div>
      <div class="receipt-no">
        <span class="label">NO:</span>
        <el-input
          v-model="formData.outboundNo"
          placeholder="单号已自动生成，可修改"
          class="no-input"
          :disabled="isReadonly"
        />
      </div>
    </div>

    <!-- 表单内容 -->
    <el-form
      ref="formRef"
      :model="formData"
      :rules="rules"
      label-width="auto"
      class="outbound-form"
    >
      <!-- 基本信息 -->
      <div class="form-row">
        <el-form-item label="操作人员" prop="operatorName">
          <el-input v-model="formData.operatorName" :disabled="isReadonly" />
        </el-form-item>

        <el-form-item label="出库时间">
          <el-input v-model="formData.outboundTime" disabled />
        </el-form-item>
      </div>

      <div class="form-row">
        <el-form-item label="审核人">
          <el-input v-model="formData.checkerName" disabled placeholder="审核后自动填写" />
        </el-form-item>

        <el-form-item label="审核时间">
          <el-input v-model="formData.checkTime" disabled placeholder="审核后自动填写" />
        </el-form-item>
      </div>

      <!-- 备注 -->
      <div class="form-row">
        <el-form-item label="备注">
          <el-input
            v-model="formData.notes"
            type="textarea"
            :rows="1"
            resize="none"
            placeholder="请输入备注信息"
            :disabled="isReadonly"
          />
        </el-form-item>
      </div>
    </el-form>

    <!-- 商品明细 -->
    <div class="goods-section">
      <div class="section-header">
        <h3>商品明细</h3>
        <el-button v-if="!isReadonly" type="primary" size="small" @click="openGoodsSelector">
          <template #icon>
            <el-icon><LineMdPlus /></el-icon>
          </template>
          添加商品
        </el-button>
      </div>

      <el-table
        :data="formData.pzGoodsOutboundDList"
        style="width: 100%"
        class="goods-table"
        :empty-text="'请添加出库商品'"
        :loading="loading"
      >
        <el-table-column label="序号" type="index" width="60" align="center" />
        <el-table-column label="商品图片" width="80" align="center">
          <template #default="{ row }">
            <el-image
              v-if="row.goodsPicture"
              :src="row.goodsPicture"
              style="width: 40px; height: 40px; border-radius: 4px"
              :preview-src-list="[row.goodsPicture]"
              fit="cover"
              preview-teleported
            />
            <div v-else class="no-image">无图片</div>
          </template>
        </el-table-column>
        <el-table-column label="商品名称" prop="goodsName" min-width="150" align="center" />
        <el-table-column label="规格" prop="specifications" min-width="100" align="center" />
        <el-table-column label="单位" prop="unit" width="80" align="center" />
        <el-table-column label="库存数量" prop="quantity" width="100" align="center" />
        <el-table-column label="出库数量" width="150" align="center">
          <template #default="{ row }">
            <!-- 只读状态下显示文本 -->
            <span v-if="isReadonly">{{ row.outQuantity }}</span>
            <!-- 编辑状态下显示数字输入框 -->
            <el-input-number
              v-else
              v-model="row.outQuantity"
              :min="1"
              :max="row.quantity && row.quantity >= 1 ? row.quantity : 1"
              :precision="0"
              style="width: 100%"
            />
          </template>
        </el-table-column>
        <el-table-column v-if="!isReadonly" label="操作" width="100" align="center">
          <template #default="{ row }">
            <el-button type="danger" size="small" circle @click="removeGoods(row)">
              <template #icon>
                <el-icon><LineMdTrash /></el-icon>
              </template>
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 底部按钮区域 -->
    <div v-if="!hideFooter" class="footer-actions">
      <!-- 新增/编辑模式 -->
      <template v-if="props.mode === 0 || props.mode === 1">
        <el-button type="primary" :loading="loading" @click="submitForm(isEdit ? 1 : 0)">
          <template #icon
            ><el-icon><LineMdPlus /></el-icon
          ></template>
          保存出库单
        </el-button>
        <el-button type="success" :loading="loading" @click="submitForm(2)">
          <template #icon
            ><el-icon><LineMdTabletArrowUp /></el-icon
          ></template>
          保存并审核
        </el-button>
        <el-button :disabled="loading" @click="cancelSubmit">
          <template #icon
            ><el-icon><LineMdClose /></el-icon
          ></template>
          取消
        </el-button>
      </template>
      <!-- 审核模式 -->
      <template v-else-if="props.mode === 2">
        <el-button type="success" :loading="loading" @click="submitForm(2)">
          <template #icon
            ><el-icon><LineMdCheckAll /></el-icon
          ></template>
          审核通过
        </el-button>
        <el-button :disabled="loading" @click="cancelSubmit">
          <template #icon
            ><el-icon><LineMdClose /></el-icon
          ></template>
          取消
        </el-button>
      </template>
      <!-- 预览模式 -->
      <template v-else-if="props.mode === 3">
        <el-button @click="cancelSubmit">
          <template #icon
            ><el-icon><LineMdClose /></el-icon
          ></template>
          关闭
        </el-button>
      </template>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.outbound-container {
  height: calc(100vh - 200px);
  display: flex;
  flex-direction: column;
  gap: 20px;
  overflow: hidden;
}

.receipt-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  flex: 0 0 auto;

  &::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -10px;
    height: 1px;
    border-radius: 10px;
    background-color: #cbcbcb;
  }

  .receipt-title {
    font-size: 28px;
    font-weight: bold;
    color: #303133;
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
  }

  .receipt-no {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;

    .label {
      font-weight: bold;
      font-size: 16px;
    }

    .no-input {
      width: 200px;
    }
  }
}

.outbound-form {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.form-row {
  display: flex;
  gap: 20px;

  :deep(.el-form-item) {
    flex: 1;
    margin-bottom: 0;
  }
}

.goods-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 15px;
  overflow: auto;

  .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;

    h3 {
      margin: 0;
      font-size: 16px;
      font-weight: bold;
    }
  }
}
.goods-table {
  border: 1px solid #ebeef5;
  border-radius: 4px;
}
.goods-table {
  .no-image {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #909399;
    background-color: #f5f7fa;
    font-size: 12px;
    border-radius: 4px;
    border: 1px dashed #d9d9d9;
    margin: 0 auto;
  }
}

.footer-actions {
  flex: 0 0 auto;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>
